package plgwsmsg

import (
	"bytes"
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/gobase"
	"golang.org/x/net/websocket"
	"strings"
)

func NewBinMsgServ(sessionPrefix string) *WsMsgServ {
	rval := NewWsMsgServ(sessionPrefix)
	rval.wsMsgType = websocket.BinaryFrame
	rval.handleRecvFunc = func(conn *WsClientConn, buf []byte) {
		r := bytes.NewReader(buf)
		s0, err := DecodeStrFromMsgPack(r)
		if err != nil {
			conn.reqDis("[err]:非法的数据包")
			return
		}
		head := gobase.NewStrMap()
		head.URLFormDecode(s0)
		action := head.Int8ByName("action", 0)
		if action == 0 {
			token := head.StringByName("token", "")
			topic := head.StringByName("topic", "")

			bodyBuf, err := DecodeBytesFromMsgPack(r)
			if err != nil {
				conn.reqDis("[err]:非法的数据包")
				return
			}

			var cache gobase.BytesBuilder
			delete(head, "token")
			cache.Reset()
			cnt := rval.ex.Pub(topic, 0, BuildBinMsgPack(&cache, head.URLFormEncode(), bodyBuf))
			if len(token) > 0 {
				cache.Reset()
				conn.SendMsgFunc(BuildBinMsgPack(&cache, fmt.Sprintf("token=%s", token), []byte(fmt.Sprintf("n=%d", cnt))))
			}
		} else if action == 1 { // sub
			token := head.StringByName("token", "")
			str := head.StringByName("topics", "")
			cnt := 0
			if len(str) > 0 {
				strs := strings.Split(str, ",")
				for i := 0; i < len(strs); i++ {
					conn.SubFunc(utils.Trim(strs[i]))
					cnt++
				}
			}
			var cache gobase.BytesBuilder
			s1 := fmt.Sprintf("n=%d&client-addr=%s&topics=%s", cnt, conn.RemoteAddr, gobase.QueryEscape(str))
			conn.SendMsgFunc(BuildBinMsgPack(&cache, fmt.Sprintf("token=%s", token), []byte(s1)))
		} else if action == 2 { // unsub
			token := head.StringByName("token", "")
			str := head.StringByName("topics", "")
			cnt := 0
			if len(str) > 0 {
				strs := strings.Split(str, ",")
				for i := 0; i < len(strs); i++ {
					topicstr := utils.Trim(strs[i])
					if len(topicstr) > 0 && conn.subchannels[topicstr] == struct{}{} {
						conn.UnsubFunc(topicstr)
						cnt++
					}
				}
			}
			var cache gobase.BytesBuilder
			s1 := fmt.Sprintf("n=%d&client-addr=%s&topics=%s", cnt, conn.RemoteAddr, gobase.QueryEscape(str))
			conn.SendMsgFunc(BuildBinMsgPack(&cache, fmt.Sprintf("token=%s", token), []byte(s1)))
		} else if action == 3 { // echo
			conn.SendMsgFunc(buf)
		}
	}
	return rval
}
